home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / public / plan / src / convert.c < prev    next >
C/C++ Source or Header  |  1994-08-01  |  8KB  |  294 lines

  1. /*
  2.  * Convert date and time data formats.
  3.  *
  4.  *    mkdatestring(time)        Convert # of seconds since 1/1/70
  5.  *                    to a date string
  6.  *    mktimestring(time, dur)        Convert # of seconds since 1/1/70
  7.  *                    to a time-of-day or duration string
  8.  *    parse_datestring(text,dtime)    Interpret the date string, and
  9.  *                    return the # of seconds since 1/1/70
  10.  *    parse_timestring(text)        Interpret the time string, and
  11.  *                    return the # of seconds since 0:00
  12.  *    parse_warnstring(text,e,l,n)    return early and late warning time,
  13.  *                    and the noalarm flag
  14.  */
  15.  
  16. #include <time.h>
  17. #include <Xm/Xm.h>
  18. #include "cal.h"
  19.  
  20. extern struct config    config;        /* global configuration data */
  21. extern time_t        tm_to_time();
  22. extern struct tm    *time_to_tm();
  23.  
  24. char *weekday_name[] =        { "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"};
  25. char *alt_weekday_name[7] = { "Mo", "Di", "Mi", "Do", "Fr", "Sa", "So" };
  26. char *monthname[] =        { "January", "February", "March", "April", "May",
  27.                   "June", "July", "August", "September", "October",
  28.                   "November", "December"};
  29.  
  30.  
  31.  
  32. /*
  33.  * return some sensible string representation of a date (no time)
  34.  */
  35.  
  36. char *mkdatestring(time)
  37.     time_t            time;        /* date in seconds */
  38. {
  39.     static char        buf[40];    /* string representation */
  40.     struct tm        *tm;        /* time to m/d/y conv */
  41.  
  42.     tm = time_to_tm(time);
  43.     if (config.mmddyy)
  44.         sprintf(buf, "%s, %d/%d/%02d",
  45.                     weekday_name[(tm->tm_wday+6)%7],
  46.                     tm->tm_mon+1, tm->tm_mday,
  47.                     tm->tm_year % 100);
  48.     else
  49.         sprintf(buf, "%s, %d.%d.%02d",
  50.                     weekday_name[(tm->tm_wday+6)%7],
  51.                     tm->tm_mday, tm->tm_mon+1,
  52.                     tm->tm_year % 100);
  53.     return(buf);
  54. }
  55.  
  56.  
  57. /*
  58.  * return some sensible string representation of a time (no date)
  59.  */
  60.  
  61. char *mktimestring(time, dur)
  62.     time_t            time;        /* date in seconds */
  63.     BOOL            dur;        /* duration, not time-of-day */
  64. {
  65.     static char        buf[40];    /* string representation */
  66.     int            hour, min;    /* time components */
  67.  
  68.     if (!dur)
  69.         time %= 86400;
  70.     time /= 60;
  71.     hour  = time / 60;
  72.     min   = time % 60;
  73.     if (config.ampm && !dur)
  74.         sprintf(buf, "%2d:%02d%c", hour%12 ? hour%12 : 12,
  75.                        min,
  76.                        hour < 12 ? 'a' : 'p');
  77.     else
  78.         sprintf(buf, "%02d:%02d",   hour, min);
  79.     return(buf);
  80. }
  81.  
  82.  
  83. /*
  84.  * parse the date string, and return the number of seconds. The default
  85.  * time argument is for the +x notation, it's typically the trigger date
  86.  * of the appointment. Use 0 if it's not available; today is default.
  87.  * Doesn't know about alpha month names yet.
  88.  */
  89.  
  90. time_t parse_datestring(text, dtime)
  91.     char            *text;        /* input string */
  92.     time_t            dtime;        /* appt start time, 0=today */
  93. {
  94.     time_t            today;        /* current date in seconds */
  95.     struct tm        *tm;        /* today's date */
  96.     long            num[3];        /* m,d,y or d,m,y */
  97.     int            nnum;        /* how many numbers in text */
  98.     long            i;        /* tmp counter */
  99.     char            *p;        /* text scan pointer */
  100.     char            buf[10];    /* lowercase weekday name */
  101.  
  102.     today  = get_time();                /* today's date */
  103.     today -= today % 86400;
  104.     tm = time_to_tm(today);
  105.     while (*text == ' ' || *text == '\t')        /* skip blanks */
  106.         text++;
  107.     for (p=text; *p; p++)                /* -> lowercase */
  108.         if (*p >= 'A' && *p <= 'Z')
  109.             *p += 'a' - 'A';
  110.  
  111.                             /* today, tomorrow? */
  112.     if (!strncmp(text, "tod", 3) ||
  113.         !strncmp(text, "heu", 3) ||
  114.         !strncmp(text, "auj", 3) || !*text)
  115.         return(today);
  116.  
  117.     if (!strncmp(text, "tom", 3) ||
  118.         !strncmp(text, "mor", 3) ||
  119.         !strncmp(text, "dem", 3))
  120.         return(today + 86400);
  121.  
  122.     if (!strncmp(text, "ueb", 3))
  123.         return(today + 2*86400);
  124.     
  125.     if (*text == '+')
  126.         return((dtime ? dtime-dtime%86400 : today)
  127.                 + atoi(text+1) * 86400);
  128.                             /* weekday name? */
  129.     for (i=0; i < 7; i++) {
  130.         strcpy(buf, weekday_name[i]);
  131.         *buf += 'a' - 'A';
  132.         if (!strncmp(buf, text, strlen(buf)))
  133.             break;
  134.         strcpy(buf, alt_weekday_name[i]);
  135.         *buf += 'a' - 'A';
  136.         if (!strncmp(buf, text, strlen(buf)))
  137.             break;
  138.     }
  139.     if (i < 7) {
  140.         i = (i - tm->tm_wday + 8) % 7;
  141.         return(today + i*86400);
  142.     }
  143.                             /* d/m/y numbers? */
  144.     num[0] = num[1] = num[2] = 0;
  145.     p = text;
  146.     for (nnum=0; nnum < 3; nnum++) {
  147.         while (*p >= '0' && *p <= '9')
  148.             num[nnum] = num[nnum]*10 + *p++ - '0';
  149.         while (*p && !(*p >= '0' && *p <= '9'))
  150.             p++;
  151.     }
  152.     if (nnum == 0)                    /* ... no numbers */
  153.         return(today);
  154.     if (nnum == 3) {                /* ... have year? */
  155.         if (num[2] < 90)
  156.             num[2] += 100;
  157.         if (num[2] > 99)
  158.             num[2] -= 1900;
  159.         if (num[2] < 90 || num[2] > 190)
  160.             num[2]  = tm->tm_year;
  161.         tm->tm_year = num[2];
  162.     }
  163.     if (nnum == 1) {                /* ... day only */
  164.         if (num[0] < tm->tm_mday)
  165.             if (++tm->tm_mon == 12) {
  166.                 tm->tm_mon = 0;
  167.                 tm->tm_year++;
  168.             }
  169.         tm->tm_mday = num[0];
  170.     } else {                    /* ... d/m or m/d */
  171.         if (config.mmddyy) {
  172.             i      = num[0];
  173.             num[0] = num[1];
  174.             num[1] = i;
  175.         }
  176.         if (nnum < 3 && num[1]*100+num[0] <
  177.                         (tm->tm_mon+1)*100+tm->tm_mday)
  178.             tm->tm_year++;
  179.         tm->tm_mday = num[0];
  180.         tm->tm_mon  = num[1]-1;
  181.     }
  182.     return(tm_to_time(tm));
  183. }
  184.  
  185.  
  186. /*
  187.  * parse the time string, and return the number of seconds.
  188.  */
  189.  
  190. time_t parse_timestring(text)
  191.     char            *text;        /* input string */
  192. {
  193.     long            num[3];        /* h,m,s */
  194.     int            nnum;        /* how many numbers in text */
  195.     int            ndigits;    /* digit counter */
  196.     char            *p = text;    /* text pointer */
  197.     int            i;        /* text index, backwards*/
  198.     char            ampm = 0;    /* 0, 'a', or 'p' */
  199.     char            sign = 0;    /* 0, '+', or '-' */
  200.     int            h, m, s;    /* hours, minutes, seconds */
  201.  
  202.     while (*p == ' ' || *p == '\t')
  203.         p++;
  204.     if (!strncmp(p, "noon", 4))
  205.         return(12*3600);
  206.     if (!strncmp(p, "midn", 4))
  207.         return(0);
  208.     if (*p == '+' || *p == '-')
  209.         sign = *p++;
  210.     while (*p == ' ' || *p == '\t')
  211.         p++;
  212.     i = strlen(p)-1;
  213.     while (i && (p[i] == ' ' || p[i] == '\t'))
  214.         i--;
  215.     if (i && p[i] == 'm')
  216.         i--;
  217.     if (i && (p[i] == 'a' || p[i] == 'p'))
  218.         ampm = p[i--];
  219.     while (i && (p[i] == ' ' || p[i] == '\t'))
  220.         i--;
  221.     num[0] = num[1] = num[2] = 0;
  222.     for (nnum=0; i >= 0 && nnum < 3; nnum++) {
  223.         ndigits = 0;
  224.         while (i >= 0 && (p[i] < '0' || p[i] > '9'))
  225.             i--;
  226.         while (i >= 0 && p[i] >= '0' && p[i] <= '9' && ndigits++ < 2)
  227.             num[nnum] += (p[i--] - '0') * (ndigits==1 ? 1 : 10);
  228.     }
  229.     if (ampm && nnum == 1) {
  230.         nnum = 2;
  231.         num[1] = num[0];
  232.         num[0] = 0;
  233.     }
  234.     switch(nnum) {
  235.       case 0:    return(get_time() % 86400);
  236.       case 1:    h = 0;        m = num[0];    s = 0;        break;
  237.       case 2:    h = num[1];    m = num[0];    s = 0;        break;
  238.       case 3:    h = num[2];    m = num[1];    s = num[0];    break;
  239.     }
  240.     if (config.ampm) {
  241.         if (ampm == 'a' && h == 12)
  242.             h = 0;
  243.         if (ampm == 'p' && h < 12)
  244.             h += 12;
  245.     }
  246.     s += h * 3600 + m * 60;
  247.     return(((sign == '+' ? get_time() + s :
  248.          sign == '-' ? get_time() - s : s) + 86400) % 86400);
  249. }
  250.  
  251.  
  252. /*
  253.  * parse the fast advance-warning string. This mode can be enabled with the
  254.  * config pulldown, and allows numeric entries like "<early>,<late>,-" that
  255.  * replace the usual popup. Not as pretty, but faster.
  256.  */
  257.  
  258. void parse_warnstring(text, early, late, noalarm)
  259.     char            *text;        /* input string */
  260.     time_t            *early, *late;    /* early and late in minutes */
  261.     BOOL            *noalarm;    /* final alarm too? */
  262. {
  263.     long            num[2], tmp;    /* early, late, swap temp */
  264.     int            nnum;        /* how many numbers in text */
  265.     char            *p;        /* text scan pointer */
  266.  
  267.     if (*text == '=') {
  268.         if (!config.late_time && !config.early_time)
  269.             config.late_time = 5*60;
  270.         *late    = config.late_time;
  271.         *early   = config.early_time;
  272.         *noalarm = FALSE;
  273.         return;
  274.     }
  275.     num[0] = num[1] = 0;
  276.     p = text;
  277.     while (*p == ' ' || *p == '\t')
  278.         p++;
  279.     for (nnum=0; nnum < 2; nnum++) {
  280.         while (*p >= '0' && *p <= '9')
  281.             num[nnum] = num[nnum]*10 + *p++ - '0';
  282.         while (*p && !strchr("0123456789-", *p))
  283.             p++;
  284.     }
  285.     *noalarm = *p == '-';
  286.     if (nnum > 1 && num[0] && num[0] < num[1]) {
  287.         tmp    = num[0];
  288.         num[0] = num[1];
  289.         num[1] = tmp;
  290.     }
  291.     config.late_time  = *late  = num[0] * 60;
  292.     config.early_time = *early = num[1] * 60;
  293. }
  294.